package com.xhwl.data.config;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.common.enums.CodeEnum;
import com.xhwl.common.exception.ApplicationException;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 14:32 2021/1/6
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ResultJson httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex) {
        log.error("HTTP请求方式不正确：【{}】", ex.getMessage());
        return ResultJson.fail(ex.getMessage());
    }

    @ExceptionHandler(value = BusinessException.class)
    public ResultJson businessException(HttpServletRequest request, BusinessException be){
        printRequestParam(request);
        log.error("业务异常", be.getMessage());
        be.printStackTrace();
        return ResultJson.fail(be.getErrorCode(), be.getMessage());
    }

    @ExceptionHandler(value = DataException.class)
    public ResultJson dataException(HttpServletRequest request, DataException da){
        printRequestParam(request);
        log.error("数据异常: 【{}】", da.getMessage());
        da.printStackTrace();
        return ResultJson.fail(CodeEnum.DATA_EXCEPTION.code, da.getMessage());
    }

    @ExceptionHandler(value = ApplicationException.class)
    public ResultJson appException(HttpServletRequest request, ApplicationException be){
        printRequestParam(request);
        log.error("应用异常: 【{}】", be.getMessage());
        return ResultJson.fail(CodeEnum.APP_EXCEPTION.code, be.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public ResultJson exception(HttpServletRequest request, RuntimeException be){
        printRequestParam(request);
        be.printStackTrace();
        return ResultJson.fail(CodeEnum.APP_EXCEPTION.code, CodeEnum.APP_EXCEPTION.description);
    }

    private static void printRequestParam(HttpServletRequest request){
        Map<String, Object> param = new HashMap<>();
        Set<String> keySet = request.getParameterMap().keySet();
        if (!keySet.isEmpty()) {
            for (String key : keySet) {
                param.put(key, (request.getParameter(key).length() > 2000 ? request.getParameter(key).substring(0, 2000) + "..." : request.getParameter(key)));
            }
        }
        log.error("request error, url: {}, params : {}", request.getRequestURI(), JSONObject.toJSONString(param));
    }

}
